package com.shashank.sony.fancywalkthroughlib;

import com.flaviofaria.kenburnsview.KenBurnsView;

import com.shashank.sony.fancywalkthroughlib.utils.ShadowTransformer;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.window.service.DisplayManager;
import ohos.agp.window.service.WindowManager;
import ohos.global.resource.NotExistException;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * FancyWalkthroughAbility
 *
 * @since 2021.07.12
 */
public abstract class FancyWalkthroughAbility extends Ability implements Component.ClickedListener {
    private static final int ZERO_PAGER = 0;

    private KenBurnsView mIvBackground;
    private Button mBtFinish;
    private DependentLayout mNavigationControls;
    private Image mIvPrev;
    private Image mIvNext;

    private int mInActiveColor;
    private int mActiveColor;

    private Font mFontType;
    private List<Integer> mColorList;

    private PageSlider mPagerSlider;
    private PageSliderIndicator mPagerSliderIndicator;
    private List<Component> mPageList = new ArrayList<>();
    private boolean isSolidBackground = false;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_ahoy);
        setStatusBackgroundColor();
        hideActionBar();

        mIvBackground = (KenBurnsView) findComponentById(ResourceTable.Id_iv_background);
        mBtFinish = (Button) findComponentById(ResourceTable.Id_bt_finish);
        mBtFinish.setClickedListener(this);
        mNavigationControls = (DependentLayout) findComponentById(ResourceTable.Id_navigation_layout);
        mIvPrev = (Image) findComponentById(ResourceTable.Id_iv_prev);
        mIvPrev.setClickedListener(this);
        mIvNext = (Image) findComponentById(ResourceTable.Id_iv_next);
        mIvNext.setClickedListener(this);

        mPagerSlider = (PageSlider) findComponentById(ResourceTable.Id_pager_slider);
        mPagerSliderIndicator = (PageSliderIndicator) findComponentById(ResourceTable.Id_pager_slider_indicator);

        initData();
    }

    /**
     * setOnboardPages
     *
     * @param pages 适配器数据
     */
    public void setOnboardPages(List<FancyWalkthroughCard> pages) {
        mPageList.clear();
        for (int i = 0; i < pages.size(); i++) {
            FancyWalkthroughFragment fancyWalkthroughFragment =
                    new FancyWalkthroughFragment(this, pages.get(i), mFontType);
            ComponentContainer.LayoutConfig layoutConfig = new ComponentContainer
                    .LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,
                    ComponentContainer.LayoutConfig.MATCH_PARENT);
            fancyWalkthroughFragment.setLayoutConfig(layoutConfig);
            mPageList.add(fancyWalkthroughFragment);
        }
        FancyWalkthroughAdapter fancyWalkthroughAdapter = new FancyWalkthroughAdapter(mPageList);
        mPagerSlider.setProvider(fancyWalkthroughAdapter);
        mPagerSlider.setCurrentPage(0);
        mPagerSlider.setSlidingPossible(true);
        ShadowTransformer mCardShadowTransformer = new ShadowTransformer(mPagerSlider, fancyWalkthroughAdapter);
        mCardShadowTransformer.enableScaling(true);
        initIndicator();
        mPagerSliderIndicator.addOnSelectionChangedListener(new PageSlider.PageChangedListener() {
            @Override
            public void onPageSliding(int var1, float var2, int var3) {
            }

            @Override
            public void onPageSlideStateChanged(int var1) {
            }

            @Override
            public void onPageChosen(int position) {
                if (isSolidBackground && (pages.size() == mColorList.size())) {
                    ShapeElement shapeElement = new ShapeElement();
                    shapeElement.setRgbColor(RgbColor.fromArgbInt(mColorList.get(position)));
                    mIvBackground.setBackground(shapeElement);
                }
                if (position == pages.size() - 1) {
                    showFinish();
                    fadeOut(mIvNext);
                    fadeIn(mIvPrev);
                } else if (position == ZERO_PAGER) {
                    fadeOut(mIvPrev);
                    fadeIn(mIvNext);
                    hideFinish();
                } else {
                    hideFinish();
                    fadeIn(mIvPrev);
                    fadeIn(mIvNext);
                }
            }
        });
    }

    private void initIndicator() {
        mPagerSliderIndicator.setViewPager(mPagerSlider);
        mPagerSliderIndicator.setItemOffset(25);
        ShapeElement activeElement = new ShapeElement(getContext(), ResourceTable.Graphic_dots_active);
        ShapeElement inActiveElement = new ShapeElement(getContext(), ResourceTable.Graphic_dots_inactive);
        inActiveElement.setBounds(0, 0, 20, 20);
        activeElement.setBounds(0, 0, 20, 20);
        if (mInActiveColor != 0) {
            inActiveElement.setRgbColor(RgbColor.fromArgbInt(mInActiveColor));
        }
        if (mActiveColor != 0) {
            activeElement.setRgbColor(RgbColor.fromArgbInt(mActiveColor));
        }
        mPagerSliderIndicator.setItemNormalElement(inActiveElement);
        mPagerSliderIndicator.setItemSelectedElement(activeElement);
    }

    /**
     * setStatusBackgroundColor
     */
    private void setStatusBackgroundColor() {
        WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.TRANSPARENT.getValue());
    }

    @Override
    public void onClick(Component component) {
        if (component == mIvPrev) {
            gotoPrevious();
        } else if (component == mIvNext) {
            gotoNext();
        } else {
            onFinishButtonPressed();
        }
    }

    /**
     * fadeOut动画
     *
     * @param view Component
     */
    private void fadeOut(Component view) {
        fadeOut(view, true);
    }

    /**
     * fadeOut动画
     *
     * @param view  Component
     * @param delay 动画持续时间
     */
    private void fadeOut(final Component view, boolean delay) {
        long duration = 0;
        if (delay) {
            duration = 300;
        }
        if (view.getVisibility() != Component.HIDE) {
            AnimatorProperty fadeOut = view.createAnimatorProperty();
            fadeOut.alphaFrom(1).alpha(0);
            fadeOut.setDuration(duration);
            fadeOut.setStateChangedListener(new MyStateChangedListener(view, false));
            fadeOut.start();
        }
    }

    /**
     * fadeIn动画
     *
     * @param view Component
     */
    private void fadeIn(final Component view) {
        if (view.getVisibility() != Component.VISIBLE) {
            AnimatorProperty fadeIn = view.createAnimatorProperty();
            fadeIn.alphaFrom(0).alpha(1);
            fadeIn.setDuration(300);
            fadeIn.setStateChangedListener(new MyStateChangedListener(view, true));
            fadeIn.start();
        }
    }

    private void showFinish() {
        mBtFinish.setVisibility(Component.VISIBLE);
        mBtFinish.setAlpha(0);
        AnimatorProperty animatorProperty = mBtFinish.createAnimatorProperty();
        animatorProperty.moveFromY(DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getRealAttributes().height).moveToY(mBtFinish.getTop()).alpha(1);
        animatorProperty.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
        animatorProperty.setDuration(500);
        animatorProperty.start();
    }

    private void hideFinish(boolean delay) {
        long duration = 0;
        if (delay) {
            duration = 250;
        }
        if (mBtFinish.getVisibility() != Component.HIDE) {
            AnimatorProperty animatorProperty = mBtFinish.createAnimatorProperty();
            animatorProperty.moveFromY(mBtFinish.getTop()).moveToY(DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getRealAttributes().height).alpha(1);
            animatorProperty.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
            animatorProperty.setDuration(duration);
            animatorProperty.setStateChangedListener(new MyStateChangedListener(mBtFinish, false));
            animatorProperty.start();
        }
    }

    private void hideFinish() {
        hideFinish(true);
    }

    private void hideActionBar() {
        getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
    }

    /**
     * onFinishButtonPressed finish按钮被点击
     */
    public abstract void onFinishButtonPressed();

    /**
     * initData 初始化数据
     */
    public abstract void initData();

    /**
     * showNavigationControls
     *
     * @param navigation 显示或隐藏
     */
    public void showNavigationControls(boolean navigation) {
        if (navigation) {
            mNavigationControls.setVisibility(Component.VISIBLE);
        } else {
            mNavigationControls.setVisibility(Component.HIDE);
        }
    }

    /**
     * setImageBackground
     *
     * @param resId 图片资源id
     */
    public void setImageBackground(int resId) {
        mIvBackground.setPixelMap(getPixelMapFromResId(resId));
    }

    private PixelMap getPixelMapFromResId(int resId) {
        InputStream stream = null;
        try {
            stream = getContext().getResourceManager().getResource(resId);
            ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
            sourceOptions.formatHint = "image/jpg";
            ImageSource imageSource = ImageSource.create(stream, sourceOptions);
            ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
            return imageSource.createPixelmap(decodingOptions);
        } catch (IOException | NotExistException e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return PixelMap.create(null);
    }

    /**
     * setColorBackground
     *
     * @param color 背景色
     */
    public void setColorBackground(int color) {
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(color));
        mIvBackground.setBackground(shapeElement);
    }

    /**
     * setColorBackground
     *
     * @param colors 背景色数组
     */
    public void setColorBackground(List<Integer> colors) {
        mColorList = colors;
        isSolidBackground = true;
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(mColorList.get(0)));
        mIvBackground.setBackground(shapeElement);
    }

    /**
     * setInactiveIndicatorColor
     *
     * @param color 原点未选中颜色
     */
    public void setInactiveIndicatorColor(int color) {
        mInActiveColor = color;
    }

    /**
     * setActiveIndicatorColor
     *
     * @param color 原点选中颜色
     */
    public void setActiveIndicatorColor(int color) {
        mActiveColor = color;
    }

    /**
     * setFinishButtonBackground
     *
     * @param element 背景属性
     */
    public void setFinishButtonBackground(Element element) {
        mBtFinish.setBackground(element);
    }

    /**
     * setFinishButtonTitle
     *
     * @param title 按钮内容
     */
    public void setFinishButtonTitle(String title) {
        mBtFinish.setText(title);
    }

    /**
     * setFinishButtonTitle
     *
     * @param titleResId 字符串id
     */
    public void setFinishButtonTitle(int titleResId) {
        mBtFinish.setText(getContext().getString(titleResId));
    }

    /**
     * setFont
     *
     * @param fontType 字体
     */
    public void setFont(Font fontType) {
        mBtFinish.setFont(fontType);
        mFontType = fontType;
    }

    private void gotoPrevious() {
        int currentPage = mPagerSlider.getCurrentPage();
        if (currentPage == ZERO_PAGER) {
            return;
        }
        mPagerSlider.setCurrentPage(mPagerSlider.getCurrentPage() - 1);
    }

    private void gotoNext() {
        int pageIndex = mPagerSlider.getCurrentPage();
        if (pageIndex == mPageList.size() - 1) {
            return;
        }
        mPagerSlider.setCurrentPage(pageIndex + 1);
    }

    /**
     * 属性动画监听类
     */
    private static class MyStateChangedListener implements Animator.StateChangedListener {
        private final Component component;
        private final boolean isVisible;

        /**
         * MyStateChangedListener instance
         *
         * @param component 控件
         * @param isVisible 是否可见
         */
        MyStateChangedListener(Component component, boolean isVisible) {
            this.component = component;
            this.isVisible = isVisible;
        }

        @Override
        public void onStart(Animator animator) {
        }

        @Override
        public void onStop(Animator animator) {
        }

        @Override
        public void onCancel(Animator animator) {
        }

        @Override
        public void onEnd(Animator animator) {
            component.setVisibility(isVisible ? Component.VISIBLE : Component.HIDE);
        }

        @Override
        public void onPause(Animator animator) {
        }

        @Override
        public void onResume(Animator animator) {
        }
    }
}
